package se.webbzon.boltzmann.configuration;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import se.webbzon.boltzmann.debug.Debug;
import se.webbzon.boltzmann.input.Input;

public class Controls {
	
	// The singleton instance of the control configuration
	private static Controls singleton; 
	
	// A collection of all the listeners to the graphic configuration instance
	private final Collection<ControlsListener> listeners;
	
	// A collection of all the available inputs
	private final List<Input> inputs;
	
	// The default input for the control configuration
	private Input input;
	
	/*============================================================
	Constructors
	============================================================*/
	
	public Controls() {
		listeners = new ArrayList<ControlsListener>();
		inputs = new ArrayList<Input>();
	}
	
	/*============================================================
	Public Methods
	============================================================*/
	
	/** Returns the singleton instance of the control configuration. **/
	public synchronized static Controls instance() {
		if (singleton == null)
			singleton = new Controls();
		return singleton;
	}
	
	/** Adds a listener to the control configuration instance. **/
	public boolean addListener(ControlsListener listener) {
		int d;
		Debug.debugCollection(this, listeners);
		return listeners.add(listener);
	}
	
	/** Removes a listener from the control configuration instance. **/
	public boolean removeListener(ControlsListener listener) {
		return listeners.remove(listener);
	}
	
	/** Clears all listeners to the control configuration instance. **/
	public void clearListeners() {
		listeners.clear();
	}
	
	/** Adds an input to the control configuration instance. **/
	public boolean addInput(Input input) {
		if (inputs.add(input)) {
			for (ControlsListener listener : listeners)
				listener.onAddInput(input);
			return true;
		} else
			return false;
	}
	
	/** Removes an input from the control configuration instance. **/
	public boolean removeInput(Input input) {
		if (inputs.remove(input)) {
			for (ControlsListener listener : listeners)
				listener.onRemoveInput(input);
			if (input == this.input)
				setInput(null);
			return true;
		} else
			return false;
	}
	
	/** Sets the input for the control configuration instance. **/
	public void setInput(Input input) {
		if (input != this.input && inputs.contains(input)) {
			Input oldInput = this.input;
			this.input = input;
			for (ControlsListener listener : listeners)
				listener.onChangeInput(oldInput,input);
		} 
	}
	
	/** Returns the input for the control configuration instance. 
	 * If null is returned then no input is set. **/
	public Input getInput() {
		return input;
	}
	
	/** Returns the number of available inputs. **/
	public int inputs() {
		return inputs.size();
	}
	
	/** Returns the (n+1):th available input. **/
	public Input getInput(int n) {
		return inputs.get(n);
	}

}
